Many modern programs execute in an environment in which memory is managed by a memory manager known as a garbage collector. In response to a request for memory, the garbage collector finds a sufficient amount of free memory and allocates it to the program. The program may then use the memory until it no longer needs the memory. The program may not explicitly inform the garbage collector that it is done using the memory. Instead, periodically, the garbage collector performs a garbage collection.
The garbage collector is responsible for determining which memory blocks are no longer being used by the program. The garbage collector may do this by traversing the objects associated with a program and marking the memory blocks they are using. If an allocated memory location is no longer referenced by an object of the program, the garbage collector may indicate that the allocated memory location may be returned to the free pool of memory locations.
The garbage collector may collect on a periodic schedule. If an object remains referenced at the end of a period, the garbage collector may determine that the object is longer-lived and place it with a collection of objects that are checked less frequently to determine if they are still referenced by the program. If an object in this collection is still referenced when the garbage collector checks the collection, the object may be moved to yet another collection of objects which is checked even less frequently. This is known as generational garbage collection, and each of these collections are known as generations. The difference in time between checking objects in one generation as compared to another generation may be 100:1 or more. Garbage collectors use various heuristics to decide when to collect various generations.
Unfortunately, objects that are in any generation may cease to be referenced immediately or shortly after being placed in the generation and continue to tie up memory until garbage collection for their generation occurs. If an object in an infrequently-collected generation has a larger size than the garbage collector is aware of, the garbage collector's heuristics may not work well and this can cause a great deal of memory to be consumed. Examples include, but are not limited to, when a small managed object references a very large amount of unmanaged memory.
What is needed is an improved method and system for tracking and garbage collecting memory of a size larger than the garbage collector is aware of.